#ifndef PTRIGGER
#define PTRIGGER

#include <vector>
#include "template.h"
#include "pBody.h"
#include "pForward.h"

namespace tmpl
{

class pTriggerCallBack
{
	friend pTrigger;
public:
	pTriggerCallBack() { mDisabled = false; IsInside = false; WasInsideLastTick = false; }
	void Tick();
	virtual void OnEnter() = 0;
	virtual void WhileInside() = 0;
	virtual void OnExit() = 0;
	bool Inside() { return IsInside; }
	bool Disabled() { return mDisabled; }
	virtual TRIGGER_TYPE GetTriggerType(){return TRIGGER_NOT_SPECIFIED;}
	virtual void BodyInside(pBody* aBody){}

protected:
	bool IsInside;
	bool WasInsideLastTick;
	pTrigger* mTrigger;
	bool mDisabled;
};

class pTriggerPickupItem : public pTriggerCallBack
{
public:
	pTriggerPickupItem(Map* aMap, Entity* aImageObject);
	void OnEnter();
	void WhileInside() {}
	void OnExit() {}
	TRIGGER_TYPE GetTriggerType(){return TRIGGER_ITEM_PICKUP;}

protected:
	Map* mMap;
	Entity* mImageObject;
};

class pTriggerGoToLevel : public pTriggerCallBack
{
public:
	pTriggerGoToLevel(char* aLevel, Map* aMap);
	void OnEnter();
	void WhileInside() {}
	void OnExit() {}
	TRIGGER_TYPE GetTriggerType(){return TIRGGER_GOTO_LEVEL;}

protected:
	Map* mMap;
	char mLevel[255];
};

class pTriggerGoToNextLevel : public pTriggerCallBack
{
public:
	pTriggerGoToNextLevel(Map* aMap);
	void OnEnter();
	void WhileInside() {}
	void OnExit() {}
	TRIGGER_TYPE GetTriggerType(){return TRIGGER_GOTO_NEXT_LEVEL;}

protected:
	Map* mMap;
};

class pTriggerWater : public pTriggerCallBack
{
public:
	pTriggerWater(vector3 aWaterSurfacePosition);
	void OnEnter();
	void WhileInside();
	void OnExit() {}
	TRIGGER_TYPE GetTriggerType(){return TRIGGER_WATER;}
	void BodyInside(pBody* aBody);
protected:
	pPlayer* mPlayer;
	vector3 mWaterSurfacePosition;
};

class pTrigger : public pBody
{
	friend pTriggerCallBack;
public:
	pTrigger(unsigned int aIndex, vector3 aPos, float aAngle, PHYSICS_MODE aMode);

	//Shape functions:
	void AddBox(vector3 aPos, vector3 aSize, float aAngle, pMaterial* aMat);
	void AddCircle(vector3 aPos, float aRadius, pMaterial* aMat);
	void AddVertices(b2Vec2 *aVertices, unsigned int aNumberOfVertices, pMaterial* aMat, b2Vec2 aOffset );
	void AddLine(vector3 aPos1, vector3 aPos2, pMaterial* aMat);

	// Trigger call back:
	void AddTriggerCallBack(pTriggerCallBack* aCallback);

	void Tick();
	ENTITY_TYPE GetType(){ return ENTITY_TRIGGER; }
	int GetTriggerCallBackCount(){return mCallBacks.size();}
	pTriggerCallBack *GetTriggerCallback(int n){return mCallBacks[n];}
public:
	std::vector<pTriggerCallBack*> mCallBacks;
};

};

#endif